#property indicator_chart_window

//1.2 20120922 smarco
//    - default ATRPeriod set to 30 
//    - default LineThickness2 set to 1 (2 is too aggressive)
//    - renamed variables (ShowBox,AdditionalLevels, etc..)
//    - unique AdditionalLevels_percent (Upper/Lower) with 0-50% check 
//    - changed vertical line "ADR Start" with "ADR (value)"
//    - cleaned "Comment" line
//
//1.1 20120903
//    - added AdditionalLevels
//    - added useAlerts

extern int TimeZoneOfData = 0;
extern int TimeZoneOfSession = 0;
extern int ATRPeriod = 30;
extern bool ShowBox = true;
extern bool UseManualADR = false;
extern int ManualADRValuePips = 0;
extern int LineStyle = 2;
extern int LineThickness1 = 1;
extern color LineColor1 = Orange;
extern int LineThickness2 = 1;
extern color LineColor2 = Red;
extern int BarForLabels = -10;
extern bool AdditionalLevels = false;
extern double AdditionalLevels_percent=20;
extern bool useAlerts = true;
extern bool DebugLogger = false;

bool alertHasNotBeenTriggered = true;
static datetime todaysTrade = 0; 

int gi_84 = 0;
int gi_88 = 24;
int g_timeframe_92 = PERIOD_D1;
bool gi_128 = TRUE;
int g_time_140 = 0;
int g_timeframe_144 = 0;
int gi_148 = -1;
double gd_152;

int init() 
{
   gd_152 = SetPoint();
   Print("Period= ", Period());
   Print("Point= ", DoubleToStr(Point, 5), " myPoint=", gd_152);
   bool li_unused_0 = StringFind(Symbol(), "JPY") != -1;
   return (0);
}

int deinit() 
{
   string l_name_0;
   int li_8 = ObjectsTotal();
   for (int l_objs_total_12 = li_8; l_objs_total_12 >= 0; l_objs_total_12--) {
      l_name_0 = ObjectName(l_objs_total_12);
      if (StringSubstr(l_name_0, 0, 5) == "[ADR]") ObjectDelete(l_name_0);
   }
   Comment("");
   return (0);
}

int start() {
   double l_open_0;
   double l_open_8;
   double ld_16;
   double ld_24;
   double ld_32;
   int li_40;
   int li_44;
   double ld_48;
   int li_56 = 0;
   int li_60 = 0;
   int li_64 = 0;
   if (Period() > PERIOD_D1) return (-1);
   
   if ((AdditionalLevels_percent < 0) || (AdditionalLevels_percent > 50)) {
      Alert("Set AdditionalLevels_percent value 0-50\n");
      AdditionalLevels_percent = 20;
   }
   
   double AdditionalLevels_percent_Upper = 100 - AdditionalLevels_percent;
   double AdditionalLevels_percent_Lower = AdditionalLevels_percent;
      
   if( iTime(NULL,PERIOD_D1,0) != todaysTrade ){
   
        alertHasNotBeenTriggered = true;
   }
   
   todaysTrade = iTime(NULL,PERIOD_D1,0);
   
  
   if (DebugLogger) {
      Print("Local time current bar:", TimeToStr(Time[0]));
      Print("Dest  time current bar: ", TimeToStr(Time[0] - 3600 * (TimeZoneOfData - TimeZoneOfSession)), ", tzdiff= ", TimeZoneOfData - TimeZoneOfSession);
   }
   ComputeDayIndices(TimeZoneOfData, TimeZoneOfSession, li_56, li_60, li_64);
   if (Time[0] == g_time_140 && Period() == g_timeframe_144 && gi_148 == li_56) {
   }
   g_timeframe_144 = Period();
   g_time_140 = Time[0];
   gi_148 = li_56;
   int li_68 = TimeZoneOfData + TimeZoneOfSession;
   int li_72 = 3600 * li_68;
   datetime l_time_76 = Time[li_56];
   double ld_80 = iATR(NULL, g_timeframe_92, ATRPeriod, 1);
   if (UseManualADR) ld_80 = ManualADRValuePips * gd_152;
   double ld_88 = 0;
   double ld_96 = 0;
   double ld_104 = 0;
   double ld_112 = 0;
   double ld_120 = 0;
   bool li_128 = FALSE;
   for (int li_132 = li_56; li_132 >= 0; li_132--) {
      li_44 = Time[li_132] - li_72;
      if (TimeHour(li_44) >= gi_84 && TimeHour(li_44) < gi_88) {
         if (ld_88 == 0.0) {
            ld_88 = Open[li_56];
            ld_112 = ld_88 + ld_80;
            ld_120 = ld_88 - ld_80;
            l_open_0 = ld_88;
            l_open_8 = ld_88;
         }
         for (int l_count_136 = 0; l_count_136 < 3; l_count_136++) {
            switch (l_count_136) {
            case 0:
               ld_48 = Low[li_132];
               break;
            case 1:
               ld_48 = High[li_132];
               break;
            case 2:
               ld_48 = Close[li_132];
            }
            ld_24 = l_open_0;
            ld_32 = l_open_8;
            li_40 = li_128;
            l_open_0 = MathMax(l_open_0, ld_48);
            l_open_8 = MathMin(l_open_8, ld_48);
            ld_16 = l_open_0 - l_open_8;
            li_128 = ld_16 >= ld_80 - gd_152 / 2.0;
            if ((!li_40) && !li_128) ld_112 = l_open_8 + ld_80;
            else {
               if ((!li_40) && li_128 && ld_48 >= ld_24) ld_112 = l_open_8 + ld_80;
               else {
                  if ((!li_40) && li_128 && ld_48 < ld_24) ld_112 = ld_24;
                  else ld_112 = ld_112;
               }
            }
            if ((!li_40) && !li_128) {
               if (DebugLogger) Print("#: ", li_132, " ", "adr_low= today_high-adr ", l_open_0, "-", ld_80, "= ", l_open_0 - ld_80);
               ld_120 = l_open_0 - ld_80;
            } else {
               if ((!li_40) && li_128 && ld_48 >= ld_32) {
                  if (DebugLogger) Print("#: ", li_132, " ", "adr_low= today_low", l_open_8);
                  ld_120 = l_open_8;
               } else {
                  if ((!li_40) && li_128 && ld_48 < ld_32) {
                     if (DebugLogger) Print("#: ", li_132, " ", "adr_low= lasthigh-adr ", ld_24, "-", ld_80, "= ", ld_24 - ld_80);
                     ld_120 = ld_24 - ld_80;
                  } else {
                     if (DebugLogger) Print("#: ", li_132, " ", "adr_low= adr_low ", ld_120);
                     ld_120 = ld_120;
                  }
               }
            }
            ld_96 = ld_112 - Close[li_132];
            ld_104 = Close[li_132] - ld_120;
            if (DebugLogger) {
               Print("#:", li_132, " ", TimeToStr(li_44, TIME_MINUTES), " High-Low/adr-Reached ", l_open_0 - l_open_8, "/", li_128);
               Print("#: ", li_132, " ", " Price= ", ld_48, " (k= ", l_count_136, " [0=low, 1=high, 2=close]])");
               Print("#: ", li_132, " ", "ADR= ", ld_80, ", O= ", l_open_0, ", P= ", l_open_8, ", Q= ", l_open_0 - l_open_8, ", R= ", li_128, ", S= ", ld_112, ", T= ", ld_120, ", U= ", ld_96, ", V= ", ld_104);
            }
         }
      }
   }
   if (DebugLogger) Print("Timezoned values: t-open= ", ld_88, ", t-high =", l_open_0, ", t-low= ", l_open_8);
   SetTimeLine("today start", "ADR ("+ DoubleToStr(MathRound(ld_80 / gd_152), 0) +")", li_56, CadetBlue, Low[li_56] - 10.0 * Point);
   int l_color_144 = LineColor1;
   int li_148 = LineThickness1;
   if (li_128) {
      l_color_144 = LineColor2;
      li_148 = LineThickness2;
      if(alertHasNotBeenTriggered && useAlerts){
         Alert(Symbol()+" 100% ADR has been triggered");
         alertHasNotBeenTriggered = false;
      }
   }
   SetLevel("ADR High", ld_112, l_color_144, LineStyle, li_148, l_time_76);
   SetLevel("ADR Low", ld_120, l_color_144, LineStyle, li_148, l_time_76);
   //additional lines. Decide if broken
   //upper line
   double add_level=ld_120+(ld_112-ld_120)*AdditionalLevels_percent_Upper/100;
   int add_color=LineColor1;
   int add_thickness=LineThickness1;
   if(High[iHighest(NULL,0,MODE_HIGH,li_56,0)]>add_level )
   {
      
      
      add_color=LineColor2;
      add_thickness=LineThickness2;
   }
   
   if( AdditionalLevels){
         SetLevel("ADR High "+DoubleToStr(AdditionalLevels_percent_Upper,0)+"%",add_level, add_color, LineStyle, add_thickness, l_time_76);
   
   }
   //lower line
   add_level=ld_120+(ld_112-ld_120)*AdditionalLevels_percent_Lower/100;
   add_color=LineColor1;
   add_thickness=LineThickness1;
   if(Low[iLowest(NULL,0,MODE_LOW,li_56,0)]<add_level)
   {
      add_color=LineColor2;
      add_thickness=LineThickness2;
   }
   if( AdditionalLevels){
   SetLevel("ADR Low "+DoubleToStr(AdditionalLevels_percent_Lower,0)+"%",add_level, add_color, LineStyle, add_thickness, l_time_76);
}
   string ls_152 = "Yes";
   if (!li_128) ls_152 = "No";
   string ls_160 =
      "ADR Value= " + DoubleToStr(MathRound(ld_80 / gd_152), 0) +
      ", Reached= " + ls_152 +
      ", Today\'s Range= " + DoubleToStr(MathRound((l_open_0 - l_open_8) / gd_152), 0) +
      ", T\'s High= " + DoubleToStr(l_open_0, Digits) +
      ", T\'s Low= " + DoubleToStr(l_open_8, Digits) +
      "\n" +
      "Target High= " + DoubleToStr(ld_112, Digits) +
      ", Target Low= " + DoubleToStr(ld_120, Digits) +
      " / To ADR High= " + DoubleToStr(MathRound(ld_96 / gd_152), 0) +
      ", To ADR Low= " + DoubleToStr(MathRound(ld_104 / gd_152), 0) + "\n";
      
   if(ShowBox)
      Comment(ls_160);

   return (0);
}

void ComputeDayIndices(int ai_0, int ai_4, int &ai_8, int &ai_12, int &ai_16) {
   int li_20;
   int li_24;
   int li_28;
   int li_32 = ai_0 + ai_4;
   int li_36 = 3600 * li_32;
   int li_40 = 1440;
   int li_44 = li_40 / Period();
   int l_day_of_week_48 = TimeDayOfWeek(Time[0] - li_36);
   int li_52 = -1;
   ai_8 = 0;
   ai_12 = 0;
   ai_16 = 0;
   switch (l_day_of_week_48) {
   case 6:
   case 0:
      li_52 = 5;
      break;
   case 1: break;
   default:
      li_52 = l_day_of_week_48 - 1;
   }
   if (DebugLogger) {
      Print("Dayofweektoday= ", l_day_of_week_48);
      Print("Dayofweekyesterday= ", li_52);
   }
   for (int l_index_60 = 0; l_index_60 <= li_44 + 1; l_index_60++) {
      li_20 = Time[l_index_60] - li_36;
      if (TimeDayOfWeek(li_20) != l_day_of_week_48) {
         ai_8 = l_index_60 - 1;
         break;
      }
   }
   for (int l_count_64 = 0; l_count_64 <= li_44 * 2 + 1; l_count_64++) {
      li_24 = Time[l_index_60 + l_count_64] - li_36;
      if (TimeDayOfWeek(li_24) == li_52) {
         ai_16 = l_index_60 + l_count_64;
         break;
      }
   }
   for (l_count_64 = 1; l_count_64 <= li_44; l_count_64++) {
      li_28 = Time[ai_16 + l_count_64] - li_36;
      if (TimeDayOfWeek(li_28) != li_52) {
         ai_12 = ai_16 + l_count_64 - 1;
         break;
      }
   }
   if (DebugLogger) {
      Print("Dest time zone\'s current day starts:", TimeToStr(Time[ai_8]), " (local time), idxbar= ", ai_8);
      Print("Dest time zone\'s previous day starts:", TimeToStr(Time[ai_12]), " (local time), idxbar= ", ai_12);
      Print("Dest time zone\'s previous day ends:", TimeToStr(Time[ai_16]), " (local time), idxbar= ", ai_16);
   }
}

void SetLevel(string as_0, double a_price_8, color a_color_16, int a_style_20, int a_width_24, int a_datetime_28) 
{
   int li_unused_32 = Digits;
   string l_name_36 = "[ADR] " + as_0 + " Label";
   string l_name_44 = "[ADR] " + as_0 + " Line";
   if (ObjectFind(l_name_44) != 0) ObjectCreate(l_name_44, OBJ_TREND, 0, a_datetime_28, a_price_8, Time[0], a_price_8);
   ObjectSet(l_name_44, OBJPROP_BACK, TRUE);
   ObjectSet(l_name_44, OBJPROP_STYLE, a_style_20);
   ObjectSet(l_name_44, OBJPROP_COLOR, a_color_16);
   ObjectSet(l_name_44, OBJPROP_WIDTH, a_width_24);
   ObjectMove(l_name_44, 1, Time[0], a_price_8);
   ObjectMove(l_name_44, 0, a_datetime_28, a_price_8);
   if (ObjectFind(l_name_36) != 0) ObjectCreate(l_name_36, OBJ_TEXT, 0, Time[0], a_price_8);
   ObjectMove(l_name_36, 0, Time[0] - 60 * (BarForLabels * Period()), a_price_8);
   string l_text_52 = " " + as_0;
   if (gi_128 && StrToInteger(as_0) == 0) l_text_52 = l_text_52 + ": " + DoubleToStr(a_price_8, Digits);
   ObjectSetText(l_name_36, l_text_52, 8, "Arial", a_color_16);
}

void SetTimeLine(string as_0, string a_text_8, int ai_16, color a_color_20, double a_price_24) {
   string l_name_32 = "[ADR] " + as_0;
   int l_time_40 = Time[ai_16];
   if (ObjectFind(l_name_32) != 0) ObjectCreate(l_name_32, OBJ_TREND, 0, l_time_40, 0, l_time_40, 100);
   ObjectMove(l_name_32, 0, l_time_40, 0);
   ObjectMove(l_name_32, 1, l_time_40, 100);
   ObjectSet(l_name_32, OBJPROP_BACK, TRUE);
   ObjectSet(l_name_32, OBJPROP_STYLE, STYLE_DOT);
   ObjectSet(l_name_32, OBJPROP_COLOR, DarkGray);
   if (ObjectFind(l_name_32 + " Label") != 0) ObjectCreate(l_name_32 + " Label", OBJ_TEXT, 0, l_time_40, a_price_24);
   ObjectMove(l_name_32 + " Label", 0, l_time_40, a_price_24);
   ObjectSetText(l_name_32 + " Label", a_text_8, 8, "Arial", a_color_20);
}

double SetPoint() {
   double ld_ret_0;
   if (Digits < 4) ld_ret_0 = 0.01;
   else ld_ret_0 = 0.0001;
   return (ld_ret_0);
}